<template>
  <div>

    <el-tooltip content="打开摄像头">
      <el-button type="success"
                 icon="el-icon-video-camera"
                 circle @click="startVideo();">

      </el-button>
    </el-tooltip>

    <el-tooltip content="关闭摄像头">
      <el-button type="warning"
                 icon="el-icon-circle-close"
                 circle @click="stopVideo();">
      </el-button>
    </el-tooltip>

    <el-tooltip content="开启连接">
      <el-button type="primary"
                 icon="el-icon-loading"
                 circle @click="connect();">

      </el-button>
    </el-tooltip>

    <el-tooltip content="断开连接">
      <el-button type="danger"
                 icon="el-icon-circle-close"
                 circle @click="hangUp();">

      </el-button>
    </el-tooltip>

    <br/>
    <div>
      <video id="local-video" autoplay style="width: 300px; height: 250px;
      border: 1px solid black;"></video>
      <video id="remote-video" autoplay style="width: 300px; height: 250px;
      border: 1px solid black;"></video>
    </div>
  </div>
</template>

<script>
export default {
  name: "media",
  data() {

    return {
      room: {
        userId: 0,
        inquiryId: 10006
      },

      socketConfig: {
        socket: '',
        socketUrl: "ws://localhost:8808/videoMedia/",
        socketRead: false
      },

      dataConfig: {
        localStream: null,
        peerConnection: null,
        peerStarted: false,
      },
      mediaConstraints: {
        mandatory: {
          OfferToReceiveAudio: false,
          OfferToReceiveVideo: true
        }
      }

    };
  },computed: {
    localVideo:() => document.getElementById('local-video'),
    remoteVideo:() => document.getElementById('remote-video')
  },
  async created(){
    // await this.getRandomUser()
    this.getInquiryInfo();
    this.webSocketInit();

  },methods:{
    //使用时需要在父组件对room 和 userid进行操作

    // getRandomUser(){
    //   this.room.userId = Math.round(Math.random()*1000)+"";
    // },
    getInquiryInfo(){
      const self = this;

      self.room.inquiryId = self.$route.query.inquiryId;
      self.room.userId = self.$route.query.userId;


    },

    //---------------webSocket 设置-------------------//
    webSocketInit(){
      const self = this;
      let conf = self.socketConfig;
      let url = conf.socketUrl
          + self.room.inquiryId
          + '/' +self.room.userId;
      conf.socket = new WebSocket(url);

      conf.socket.onopen = self.wsOnOpen;

      conf.socket.onclose = self.wsOnClose;

      conf.socket.onmessage = self.wsOnMessage;


    },
    wsOnOpen(){
      console.log("成功连接到服务器...")
      this.socketConfig.socketRead = true;
    },

    wsOnClose(e){
      console.log("与服务器连接失败..."+e.code);
      this.socketConfig.socketRead = false;
    },

    wsOnMessage(res){
      var evt  = JSON.parse(res.data);
      console.log(evt)
      let peerStarted = this.dataConfig.peerStarted;

      //接收到offer SDP 解析 SDP 向 offer发送方 发送 answer SDP
      if(evt.type === 'offer'){
        console.log("接收到offer，设置offer，发送answer...")
        this.onOffer(evt);
      }
      //接收到 answer SDP 解析 SDP
      else if (evt.type === 'answer' && peerStarted){
        console.log('接收到answer,设置answer SDP')
        this.onAnswer(evt);
      }
      else if (evt.type === 'candidate' && peerStarted){
        console.log('接收到ICE候选者..');
        this.onCandidate(evt);
      }
      else if(evt.type === 'bye' && peerStarted){
        console.log("WebRTC通信断开");
        this.stop();
      }
    },
    //-----------------交换信息------------------------
    onOffer(evt) {
      console.log("接收到 offer...");
      console.log(evt);
      this.setOffer(evt);
      this.sendAnswer(evt);
      this.dataConfig.peerStarted = true;
    },
    onAnswer(evt) {
      console.log("接收到Answer...")
      console.log(evt);
      this.setAnswer(evt);
    },
    onCandidate(evt) {
      let candidate = new RTCIceCandidate({
        sdpMLineIndex: evt.sdpMLineIndex,
        sdpMid: evt.sdpMid, candidate: evt.candidate
      });
      console.log("接收到Candidate...");
      console.log(candidate);
      this.dataConfig.peerConnection.addIceCandidate(candidate);

    },

    sendSDP(sdp){
      let text = JSON.stringify(sdp);
      console.log('发送sdp.....')
      console.log(text); // "type":"offer"....

      // 通过socket发送sdp
      this.socketConfig.socket.send(text);
    },
    sendCandidate(candidate) {
      let text = JSON.stringify(candidate);
      console.log(text);// "type":"candidate","sdpMLineIndex":0,"sdpMid":"0","candidate":"....
      this.socketConfig.socket.send(text)// socket发送
    },
//---------------------- 视频处理 -----------------------
    startVideo() {
      const dataCfg = this.dataConfig;
      const self = this;
      navigator.mediaDevices.getUserMedia({ video: true, audio: false })
          .then(function (stream) { //success
            dataCfg.localStream = stream;
            self.localVideo.srcObject = stream;

            self.localVideo.play();
            self.localVideo.volume = 0;
          })
          .catch(function (error) { //error
            console.error('发生了一个错误: [错误代码：' + error.code + ']');
            return;
          });
    },
    stopVideo() {
      this.localVideo.src = "";
      this.dataConfig.localStream.stop();
    },
    //---------------------- 处理连接 -----------------------
    prepareNewConnection() {
      let pc_config = { "iceServers": [] };
      let peer = null;
      const self = this;
      const dataCfg = this.dataConfig;
      try {
        peer = new webkitRTCPeerConnection(pc_config);
      }
      catch (e) {
        console.log("建立连接失败，错误：" + e.message);
      }

      // 发送所有ICE候选者给对方
      peer.onicecandidate = function (evt) {
        if (evt.candidate) {
          console.log(evt.candidate);
          self.sendCandidate({
            type: "candidate",
            sdpMLineIndex: evt.candidate.sdpMLineIndex,
            sdpMid: evt.candidate.sdpMid,
            candidate: evt.candidate.candidate
          });
        }
      };
      console.log('添加本地视频流...');
      peer.addStream(dataCfg.localStream);

      // 当接收到远程视频流时，使用本地video元素进行显示
      peer.addEventListener("addstream", self.onRemoteStreamAdded, false);

      // 当远程结束通信时，取消本地video元素中的显示
      peer.addEventListener("removestream", self.onRemoteStreamRemoved, false);


      return peer;
    },

    onRemoteStreamAdded(event) {
      const self = this;
      console.log("添加远程视频流");
      // remoteVideo.src = window.URL.createObjectURL(event.stream);
      self.remoteVideo.srcObject = event.stream;
    },

    onRemoteStreamRemoved(event) {
      const self = this;
      console.log("移除远程视频流");
      self.remoteVideo.src = "";
    },



    //------------------------------------
    sendOffer() {
      const self = this;
      const conf = this.dataConfig;
      const socketCfg = this.socketConfig;
      conf.peerConnection = self.prepareNewConnection();
      conf.peerConnection.createOffer(function (sessionDescription) { //成功时调用
        conf.peerConnection.setLocalDescription(sessionDescription);
        console.log("发送: SDP");
        console.log(sessionDescription);
        self.sendSDP(sessionDescription);
      }, function (err) {  //失败时调用
        console.log("创建Offer失败");
      }, self.mediaConstraints);
    },



    setOffer(evt) {
      const self = this;
      const conf = this.dataConfig;
      if (conf.peerConnection) {
        console.error('peerConnection已存在!');
        return;
      }
      conf.peerConnection = self.prepareNewConnection();
      conf.peerConnection.setRemoteDescription(new RTCSessionDescription(evt));
    },

    sendAnswer(evt) {
      const self = this;
      const conf = this.dataConfig;
      console.log('发送Answer,创建远程会话描述...');
      if (!conf.peerConnection) {
        console.error('peerConnection不存在!');
        return;
      }

      conf.peerConnection.createAnswer(function (sessionDescription) {//成功时
          conf.peerConnection.setLocalDescription(sessionDescription);
          console.log("发送: SDP");
          console.log(sessionDescription);
          self.sendSDP(sessionDescription);
        }, function () {                                             //失败时
            console.log("创建Answer失败");
        }, self.mediaConstraints);
    },

    setAnswer(evt) {
      const conf = this.dataConfig;
      if (!conf.peerConnection) {
        console.error('peerConnection不存在!');
        return;
      }
      conf.peerConnection.setRemoteDescription(new RTCSessionDescription(evt));
    },
    //-----------------ui触发-------------------
    // 开始建立连接
    connect() {
      const self = this;
      const conf = this.dataConfig;
      const socketCfg = this.socketConfig;
      if (!conf.peerStarted && conf.localStream && socketCfg.socketRead) {
        self.sendOffer();
        self.dataConfig.peerStarted = true;
      } else {
        alert("请首先捕获本地视频数据.");
      }
    },

    // 停止连接
    hangUp() {
      console.log("挂断.");
      this.stop();
    },

    stop() {
      const conf = this.dataConfig;
      conf.peerConnection.close();
      conf.peerConnection = null;
      conf.peerStarted = false;
    }

  }
}
</script>

<style scoped>

</style>